import 'dart:io';
import 'dart:ui';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:xws/helpers/routes/slide_up_route.dart';
import 'package:xws/helpers/routes/transparent_route.dart';
import 'package:xws/ui/login/login_page.dart';
import 'package:xws/widgets/bottom_sheet/options_sheet.dart';
import 'package:xws/widgets/dialog/dialog_bg.dart';
import 'package:xws/widgets/dialog/loading_dialog.dart';
import 'package:xws/widgets/dialog/tips.dart';
import 'package:xws/widgets/toasts/point_ch.dart';
import 'package:xws/widgets/toasts/toast_bg.dart';

import 'log_util.dart';
import 'storage_util.dart';

/// 路由样式
enum RouteType { ios, android, fade, slideUp }

/// 单例存储
class _A {
  const _A._();

  static final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();

  /// toast
  static final FToast _fToast = FToast();

  /// showToast
  static void _showToast({
    required Widget child,
    PositionedToastBuilder? positionedToastBuilder,
    Duration? toastDuration,
    ToastGravity gravity = ToastGravity.CENTER,
    int fadeDuration = 100,
  }) {
    _fToast.showToast(
      child: child,
      positionedToastBuilder: positionedToastBuilder,
      toastDuration: toastDuration,
      gravity: gravity,
      fadeDuration: fadeDuration,
    );
  }
}

/// 暴露全局navigatorKey
GlobalKey<NavigatorState> get appNavigatorKey => _A._navigatorKey;

/// 是否登录
bool get isLogin {
  final String? token = getV<String>('token');
  return token != null && token.isNotEmpty;
}

/// * 检测是否登录
/// * 未登录自动跳转到登录
bool get checkUserLogin {
  if (isLogin) return true;

  pushWithoutContext(const LoginPage(withBack: true));

  return false;
}

/// 初始化toast
void initToast(BuildContext context) {
  _A._fToast.init(context);
}

/// 成功toast
void st([String t = 'success', Duration? duration]) => _A._showToast(
      child: ToastBg.success(content: t),
      toastDuration: duration,
    );

/// 错误toast
void et([String t = 'error', Duration? duration]) => _A._showToast(
      child: ToastBg.error(content: t),
      toastDuration: duration,
    );

/// 自定义toast
void ct([
  String t = 'info',
  Duration? duration,
  IconData icon = Icons.notifications_rounded,
]) =>
    _A._showToast(
      child: ToastBg.info(content: t, icon: icon),
      toastDuration: duration,
    );

/// 积分变动弹框
void pointToast(String content) {
  _A._showToast(
    gravity: ToastGravity.BOTTOM,
    toastDuration: const Duration(seconds: 1),
    child: PointCh(content: content),
  );
}

/// 路由类型对象
Route<T> _getPageRoute<T>(RouteType type, Widget page) {
  switch (type) {
    case RouteType.ios:
      return CupertinoPageRoute<T>(builder: (_) => page);
    case RouteType.android:
      return MaterialPageRoute<T>(builder: (_) => page);
    case RouteType.fade:
      return TransparentRoute<T>(builder: (_) => page);
    case RouteType.slideUp:
      return SlideUpRoute<T>(builder: (_) => page);
    default:
      break;
  }

  return CupertinoPageRoute<T>(builder: (_) => page);
}

/// 简单的跳转封装
Future<T?> push<T extends Object?>(
  BuildContext context,
  Widget page, {
  bool remove = false,
  RouteType routeType = RouteType.ios,
}) async {
  try {
    if (remove) {
      return await Navigator.of(context).pushAndRemoveUntil<T>(
        _getPageRoute<T>(routeType, page),
        (_) => false,
      );
    }
    return await Navigator.of(context).push<T>(
      _getPageRoute<T>(routeType, page),
    );
  } catch (e) {
    error('路由跳转出错:$e');
  }
}

/// 简单的跳转封装
Future<T?> pushWithoutContext<T extends Object?>(
  Widget page, {
  bool remove = false,
  RouteType routeType = RouteType.ios,
}) async {
  try {
    if (remove) {
      return await Navigator.of(appNavigatorKey.currentContext!).pushAndRemoveUntil<T>(
        _getPageRoute<T>(routeType, page),
        (_) => false,
      );
    }
    return await Navigator.of(appNavigatorKey.currentContext!).push<T>(
      _getPageRoute<T>(routeType, page),
    );
  } catch (e) {
    error('路由跳转出错:$e');
  }
}

/// 简单的路由销毁封装
void pop(BuildContext context, {dynamic value, bool ex = false}) {
  if (ex) {
    SystemNavigator.pop();
    if (Platform.isIOS) exit(0);
  } else
    Navigator.pop(context, value);
}

/// 简单的弹窗关闭封装
void close(BuildContext context, {dynamic value}) => Navigator.pop(context, value);

/// 提示对话框
Future<T?> tips<T extends Object>(
  String content, {
  String title = '提示',
  Function()? onCheck,
  Function()? onCancel,
  String? checkText,
  String? cancelText,
}) async =>
    await _sysDialog(
      _A._navigatorKey.currentContext!,
      Tips(
        content: content,
        title: title,
        onCheck: onCheck,
        onCancel: onCancel,
        checkText: checkText,
        cancelText: cancelText,
      ),
    );

/// 自定义对话框
Future<T?> customDialog<T extends Object>(
  Widget child, {
  bool? allowBack,
  Color? barrierColor,
}) async =>
    await _sysDialog(
      _A._navigatorKey.currentContext!,
      child,
      allowBack: allowBack,
      barrierColor: barrierColor,
    );

/// 显示原始底部弹框
Future<T?> showBottom<T>(
  BuildContext context,
  Widget child, {
  Color? barrierColor,
  Color? backgroundColor,
  ShapeBorder? shape,
}) async {
  return await showModalBottomSheet<T>(
    context: context,
    elevation: 0,
    isScrollControlled: true,
    barrierColor: barrierColor ?? Colors.black12,
    backgroundColor: backgroundColor,
    shape: shape,
    builder: (_) => child,
  );
}

/// 显示选项底部弹框
Future<T?> showOptions<T>(
  BuildContext context, {
  Widget? child,
  Color? barrierColor,
  EdgeInsetsGeometry? padding,
  String? title,
  Color? backgroundColor,
  List<String> options = const <String>[],
}) async {
  return await showBottom<T>(
    context,
    OptionsSheet(
      child: child,
      padding: padding,
      title: title,
      options: options,
      backgroundColor: backgroundColor ?? Colors.transparent,
    ),
    barrierColor: barrierColor ?? Colors.black26,
    backgroundColor: Colors.transparent,
  );
}

/// 加载动画弹框
Future<T?> loading<T extends Object>(BuildContext context) async =>
    await _sysDialog<T>(context, const LoadingDialog(), allowBack: false);

/// 系统对话框封装
Future<T?> _sysDialog<T>(BuildContext context, Widget child, {bool? allowBack, Color? barrierColor}) async {
  return await showGeneralDialog<T?>(
    barrierColor: barrierColor ?? const Color(0x80000000),
    context: context,
    pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) => DialogBg(
      child: child,
      allowBack: allowBack ?? true,
    ),
  );
}
